<template>
  <view class="file-upload-component">
    <!-- 上传区域 -->
    <view 
      class="upload-area" 
      :class="{ 'drag-over': dragOver, 'disabled': disabled }"
      @tap="chooseFile"
    >
      <view v-if="!selectedFiles.length" class="upload-placeholder">
        <u-icon name="cloud-upload" size="40" color="#c0c4cc"></u-icon>
        <text class="placeholder-text">{{ placeholder }}</text>
        <text class="placeholder-tips">{{ tips }}</text>
      </view>
      
      <view v-else class="selected-files">
        <view 
          v-for="(file, index) in selectedFiles" 
          :key="index"
          class="file-item"
        >
          <view class="file-info">
            <u-icon :name="getFileIcon(file.type)" size="20" color="#409eff"></u-icon>
            <view class="file-details">
              <text class="file-name">{{ file.name }}</text>
              <text class="file-size">{{ formatFileSize(file.size) }}</text>
            </view>
          </view>
          
          <view class="file-actions">
            <u-icon 
              v-if="!uploading"
              name="close-circle" 
              size="18" 
              color="#f56c6c" 
              @tap.stop="removeFile(index)"
            />
          </view>
          
          <!-- 上传进度 -->
          <view v-if="file.uploading" class="upload-progress">
            <u-line-progress 
              :percent="file.progress" 
              :show-percent="false"
              active-color="#409eff"
              height="4"
            />
          </view>
          
          <!-- 上传状态 -->
          <view class="upload-status">
            <u-icon 
              v-if="file.status === 'success'"
              name="checkmark-circle" 
              size="16" 
              color="#67c23a"
            />
            <u-icon 
              v-else-if="file.status === 'error'"
              name="close-circle" 
              size="16" 
              color="#f56c6c"
            />
            <u-loading-icon 
              v-else-if="file.uploading"
              mode="circle" 
              size="16"
            />
          </view>
        </view>
      </view>
    </view>
    
    <!-- 操作按钮 -->
    <view v-if="showButtons" class="action-buttons">
      <u-button 
        v-if="!autoUpload"
        type="primary" 
        size="small"
        :disabled="!selectedFiles.length || uploading"
        :loading="uploading"
        @click="startUpload"
      >
        {{ uploading ? '上传中...' : '开始上传' }}
      </u-button>
      
      <u-button 
        type="info" 
        size="small"
        :disabled="uploading"
        @click="clearFiles"
      >
        清空
      </u-button>
    </view>
    
    <!-- 错误信息 -->
    <view v-if="errorMessage" class="error-message">
      <u-icon name="info-circle" size="14" color="#f56c6c"></u-icon>
      <text>{{ errorMessage }}</text>
    </view>
  </view>
</template>

<script>
export default {
  name: 'FileUpload',
  props: {
    // 是否多选
    multiple: {
      type: Boolean,
      default: false
    },
    // 最大文件数量
    maxCount: {
      type: Number,
      default: 1
    },
    // 最大文件大小(MB)
    maxSize: {
      type: Number,
      default: 50
    },
    // 允许的文件类型
    accept: {
      type: Array,
      default: () => ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'jpg', 'jpeg', 'png', 'gif', 'bmp']
    },
    // 是否自动上传
    autoUpload: {
      type: Boolean,
      default: true
    },
    // 是否显示操作按钮
    showButtons: {
      type: Boolean,
      default: true
    },
    // 是否禁用
    disabled: {
      type: Boolean,
      default: false
    },
    // 占位符文本
    placeholder: {
      type: String,
      default: '点击选择文件'
    },
    // 提示文本
    tips: {
      type: String,
      default: '支持PDF、Word、Excel、PPT、图片等格式'
    }
  },
  
  data() {
    return {
      selectedFiles: [],
      uploading: false,
      dragOver: false,
      errorMessage: ''
    }
  },
  
  methods: {
    // 选择文件
    chooseFile() {
      if (this.disabled || this.uploading) return
      
      const count = this.multiple ? this.maxCount : 1
      
      uni.chooseFile({
        count,
        type: 'file',
        extension: this.accept,
        success: (res) => {
          this.handleFiles(res.tempFiles)
        },
        fail: (err) => {
          console.error('选择文件失败:', err)
          this.showError('选择文件失败')
        }
      })
    },
    
    // 处理选中的文件
    handleFiles(files) {
      this.errorMessage = ''
      
      for (const file of files) {
        // 检查文件数量限制
        if (this.selectedFiles.length >= this.maxCount) {
          this.showError(`最多只能选择${this.maxCount}个文件`)
          break
        }
        
        // 检查文件大小
        if (file.size > this.maxSize * 1024 * 1024) {
          this.showError(`文件"${file.name}"大小超过${this.maxSize}MB限制`)
          continue
        }
        
        // 检查文件类型
        const extension = file.name.split('.').pop().toLowerCase()
        if (!this.accept.includes(extension)) {
          this.showError(`不支持的文件类型: ${extension}`)
          continue
        }
        
        // 添加文件到列表
        const fileItem = {
          ...file,
          id: Date.now() + Math.random(),
          uploading: false,
          progress: 0,
          status: 'ready'
        }
        
        this.selectedFiles.push(fileItem)
      }
      
      // 自动上传
      if (this.autoUpload && this.selectedFiles.some(f => f.status === 'ready')) {
        this.startUpload()
      }
      
      this.$emit('change', this.selectedFiles)
    },
    
    // 移除文件
    removeFile(index) {
      this.selectedFiles.splice(index, 1)
      this.$emit('change', this.selectedFiles)
    },
    
    // 清空文件
    clearFiles() {
      this.selectedFiles = []
      this.errorMessage = ''
      this.$emit('change', this.selectedFiles)
    },
    
    // 开始上传
    async startUpload() {
      if (this.uploading) return
      
      this.uploading = true
      this.errorMessage = ''
      
      const readyFiles = this.selectedFiles.filter(f => f.status === 'ready')
      
      for (const file of readyFiles) {
        try {
          await this.uploadSingleFile(file)
        } catch (error) {
          console.error('上传文件失败:', error)
          file.status = 'error'
          file.uploading = false
        }
      }
      
      this.uploading = false
      
      // 检查上传结果
      const successFiles = this.selectedFiles.filter(f => f.status === 'success')
      const errorFiles = this.selectedFiles.filter(f => f.status === 'error')
      
      if (successFiles.length > 0) {
        this.$emit('success', successFiles)
      }
      
      if (errorFiles.length > 0) {
        this.$emit('error', errorFiles)
      }
    },
    
    // 上传单个文件
    uploadSingleFile(file) {
      return new Promise((resolve, reject) => {
        file.uploading = true
        file.status = 'uploading'
        
        const uploadTask = uni.uploadFile({
          url: this.$config.baseURL + '/api/files/upload',
          filePath: file.path,
          name: 'file',
          header: {
            'Authorization': 'Bearer ' + this.$store.state.user.token
          },
          success: (res) => {
            if (res.statusCode === 200) {
              const data = JSON.parse(res.data)
              if (data.success) {
                file.status = 'success'
                file.result = data.data
                resolve(data.data)
              } else {
                throw new Error(data.message || '上传失败')
              }
            } else {
              throw new Error('上传失败')
            }
          },
          fail: (err) => {
            reject(new Error('网络错误，上传失败'))
          },
          complete: () => {
            file.uploading = false
          }
        })
        
        // 监听上传进度
        uploadTask.onProgressUpdate((res) => {
          file.progress = res.progress
        })
      })
    },
    
    // 显示错误信息
    showError(message) {
      this.errorMessage = message
      setTimeout(() => {
        this.errorMessage = ''
      }, 3000)
    },
    
    // 获取文件图标
    getFileIcon(fileType) {
      if (!fileType) return 'file-text'
      
      if (fileType.includes('pdf')) return 'file-pdf'
      if (fileType.includes('word') || fileType.includes('document')) return 'file-word'
      if (fileType.includes('excel') || fileType.includes('sheet')) return 'file-excel'
      if (fileType.includes('powerpoint') || fileType.includes('presentation')) return 'file-ppt'
      if (fileType.includes('image')) return 'image'
      if (fileType.includes('text')) return 'file-text'
      
      return 'file'
    },
    
    // 格式化文件大小
    formatFileSize(bytes) {
      if (bytes === 0) return '0 B'
      const k = 1024
      const sizes = ['B', 'KB', 'MB', 'GB']
      const i = Math.floor(Math.log(bytes) / Math.log(k))
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
    }
  }
}
</script>

<style lang="scss" scoped>
.file-upload-component {
  width: 100%;
}

.upload-area {
  border: 2rpx dashed #dcdfe6;
  border-radius: 12rpx;
  padding: 40rpx;
  text-align: center;
  transition: all 0.3s;
  
  &:not(.disabled):active {
    border-color: #409eff;
    background-color: #f0f9ff;
  }
  
  &.drag-over {
    border-color: #409eff;
    background-color: #f0f9ff;
  }
  
  &.disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }
}

.upload-placeholder {
  .placeholder-text {
    display: block;
    margin-top: 20rpx;
    font-size: 32rpx;
    color: #606266;
    font-weight: 500;
  }
  
  .placeholder-tips {
    display: block;
    margin-top: 12rpx;
    font-size: 26rpx;
    color: #909399;
  }
}

.selected-files {
  text-align: left;
  
  .file-item {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 20rpx;
    margin-bottom: 16rpx;
    background-color: #f8f9fa;
    border-radius: 12rpx;
    
    &:last-child {
      margin-bottom: 0;
    }
    
    .file-info {
      display: flex;
      align-items: center;
      flex: 1;
      
      .file-details {
        margin-left: 16rpx;
        
        .file-name {
          display: block;
          font-size: 28rpx;
          color: #303133;
          font-weight: 500;
          margin-bottom: 6rpx;
        }
        
        .file-size {
          font-size: 24rpx;
          color: #909399;
        }
      }
    }
    
    .file-actions {
      margin-left: 20rpx;
    }
    
    .upload-progress {
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      height: 4rpx;
    }
    
    .upload-status {
      margin-left: 12rpx;
    }
  }
}

.action-buttons {
  display: flex;
  gap: 20rpx;
  margin-top: 30rpx;
  
  .u-button {
    flex: 1;
  }
}

.error-message {
  display: flex;
  align-items: center;
  margin-top: 20rpx;
  padding: 16rpx 20rpx;
  background-color: #fef0f0;
  border-radius: 8rpx;
  
  text {
    margin-left: 12rpx;
    font-size: 26rpx;
    color: #f56c6c;
  }
}
</style>